package com.logos.musicframe.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.logos.musicframe.constant.MqConstant;
import com.logos.musicframe.constant.RedisConstant;
import com.logos.musicframe.converter.PlaylistCollectedConverter;
import com.logos.musicframe.entity.Playlist;
import com.logos.musicframe.entity.PlaylistCollectCount;
import com.logos.musicframe.entity.PlaylistCollected;
import com.logos.musicframe.mapper.PlaylistCollectedMapper;
import com.logos.musicframe.req.PlaylistCollectedReq;
import com.logos.musicframe.resp.PlaylistResp;
import com.logos.musicframe.service.PlaylistCollectedService;
import com.logos.musicframe.service.PlaylistService;
import com.logos.musicframe.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (PlaylistCollected)表服务实现类
 *
 * @author logos
 * @since 2025-06-15 12:32:44
 */
@Service("playlistCollectedService")
@Slf4j
public class PlaylistCollectedServiceImpl implements PlaylistCollectedService {

    @Autowired
    private PlaylistCollectedMapper playlistCollectedMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private PlaylistService playlistService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public PlaylistCollected queryById(Long id) {
        return this.playlistCollectedMapper.queryById(id);
    }

    /**
     * 分页查询
     *
     * @param playlistCollected 筛选条件
     * @param pageRequest       分页对象
     * @return 查询结果
     */
    @Override
    public Page<PlaylistCollected> queryByPage(PlaylistCollected playlistCollected, PageRequest pageRequest) {
        long total = this.playlistCollectedMapper.count(playlistCollected);
        return new PageImpl<>(this.playlistCollectedMapper.queryAllByLimit(playlistCollected, pageRequest), pageRequest, total);
    }

    /**
     * 新增数据
     *
     * @param playlistCollected 实例对象
     * @return 实例对象
     */
    @Override
    public PlaylistCollected insert(PlaylistCollected playlistCollected) {
        this.playlistCollectedMapper.insert(playlistCollected);
        return playlistCollected;
    }

    /**
     * 修改数据
     *
     * @param playlistCollected 实例对象
     * @return 实例对象
     */
    @Override
    public PlaylistCollected update(PlaylistCollected playlistCollected) {
        this.playlistCollectedMapper.update(playlistCollected);
        return this.queryById(playlistCollected.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        return this.playlistCollectedMapper.deleteById(id) > 0;
    }

    /**
     * 收藏歌单
     *
     * @param playlistCollectedReq
     * @return
     */
    @Override
    public Boolean collect(PlaylistCollectedReq playlistCollectedReq) {
        Integer userId = playlistCollectedReq.getUserId();
        Integer playlistId = playlistCollectedReq.getPlaylistId();
        // 利用mq去发送收藏消息
        try {
            PlaylistCollected playlistCollected = new PlaylistCollected().setUserId(userId).setPlaylistId(playlistId);
            rabbitTemplate.convertAndSend(MqConstant.PLAYLIST_EXCHANGE, MqConstant.PLAYLIST_COLLECTED_ROUTING_KEY, playlistCollected);
        } catch (Exception e) {
            log.error("发送消息失败：{}", e.getMessage());
            return false;
        }
        // 利用mq去增加数据库中收藏个数
        try {
            PlaylistCollectCount playlistCollectCount = new PlaylistCollectCount().setPlaylistId(Long.valueOf(playlistId)).setCount(1L);
            rabbitTemplate.convertAndSend(MqConstant.PLAYLIST_EXCHANGE, MqConstant.PLAYLIST_COLLECT_COUNT_ROUTING_KEY, playlistCollectCount);
        } catch (Exception e) {
            log.error("发送消息失败：{}", e.getMessage());
            return false;
        }
        // 歌单排行榜+1
        redisUtil.addScore(RedisConstant.PLAYLIST_RANK, String.valueOf(playlistId), 1L);
        // 清除当前用户的歌单数据
        redisUtil.del(RedisConstant.PLAYLIST_COLLECTED_USER + userId);
        return true;
    }

    /**
     * 取消收藏歌单
     *
     * @param playlistCollectedReq
     * @return
     */
    @Override
    public Boolean unCollect(PlaylistCollectedReq playlistCollectedReq) {
        Integer userId = playlistCollectedReq.getUserId();
        Integer playlistId = playlistCollectedReq.getPlaylistId();
        // 利用mq去发送取消收藏消息
        try {
            PlaylistCollected playlistCollected = new PlaylistCollected().setUserId(userId).setPlaylistId(playlistId);
            rabbitTemplate.convertAndSend(MqConstant.PLAYLIST_EXCHANGE, MqConstant.PLAYLIST_UNCOLLECTED_ROUTING_KEY, playlistCollected);
        } catch (Exception e) {
            log.error("发送消息失败：{}", e.getMessage());
            return false;
        }
        // 利用mq去减少数据库中收藏个数
        try {
            PlaylistCollectCount playlistCollectCount = new PlaylistCollectCount().setPlaylistId(Long.valueOf(playlistId)).setCount(-1L);
            rabbitTemplate.convertAndSend(MqConstant.PLAYLIST_EXCHANGE, MqConstant.PLAYLIST_COLLECT_COUNT_ROUTING_KEY, playlistCollectCount);
        } catch (Exception e) {
            log.error("发送消息失败：{}", e.getMessage());
            return false;
        }
        // 歌单排行榜-1
        redisUtil.addScore(RedisConstant.PLAYLIST_RANK, String.valueOf(playlistId), -1L);
        // 清除当前用户的歌单数据
        redisUtil.del(RedisConstant.PLAYLIST_COLLECTED_USER + userId);
        return true;
    }

    @Override
    public List<PlaylistResp> queryByUserId(Integer userId) {
        // 查询是否命中了缓存
        String userCollectedPlaylistKey = RedisConstant.PLAYLIST_COLLECTED_USER + userId;
        if (redisUtil.exist(userCollectedPlaylistKey)) {
            List<PlaylistResp> playlistRespList = JSONObject.parseArray(redisUtil.get(userCollectedPlaylistKey), PlaylistResp.class);
            log.info("playlistService.queryByUserId.Cache.Hit:{}", playlistRespList);
            return playlistRespList;
        }
        // 根据用户id查询
        List<PlaylistCollected> playlistCollectedList = playlistCollectedMapper.queryByUserId(userId);
        if (playlistCollectedList == null || playlistCollectedList.size() == 0) {
            return new ArrayList<>();
        }
        List<Long> playListId = playlistCollectedList.stream().map(playlistCollected -> Long.valueOf(playlistCollected.getPlaylistId())).collect(Collectors.toList());
        // 根据歌单id查询歌单
        List<PlaylistResp> playlistRespList = playlistService.queryByIds(playListId);
        playlistRespList.forEach(playlistResp -> {
            playlistResp.setIsCollected(true);
        });
        // 设置缓存
        redisUtil.setNx(RedisConstant.PLAYLIST_COLLECTED_USER + userId, JSONObject.toJSONString(playlistRespList), RedisConstant.EXPIRE_TIME_THREE_MINUTES);
        return playlistRespList;
    }
}
